
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>2、Gradle进阶 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>2、Gradle进阶 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">在管理依赖时，为何推荐使用 `implementation` 代替旧的 `compile` 配置？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">推荐使用 `implementation` 是为了避免将依赖传递给消费该模块的其他项目，从而防止依赖泄露。这有助于提高构建速度和模块化程度。</div>
          </div>
          <div class="card-source">来源: 1. 依赖管理深入 - 依赖配置策略</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">文档中介绍了哪三种解决依赖冲突的方法？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">文档中介绍了三种方法：1. 使用 `resolutionStrategy.force` 强制指定一个版本；2. 在依赖声明中使用 `exclude` 关键字排除特定的传递性依赖；3. 使用 `dependencyLocking` 功能来锁定所有配置的依赖版本。</div>
          </div>
          <div class="card-source">来源: 1. 依赖管理深入 - 依赖冲突解决</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在自定义Task时，`dependsOn` 和 `finalizedBy` 这两个依赖控制指令有什么不同？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`dependsOn` 用于声明当前任务必须在另一个任务执行完毕后才能开始执行。而 `finalizedBy` 用于声明一个任务，该任务将在当前任务执行结束后（无论成功或失败）被执行。</div>
          </div>
          <div class="card-source">来源: 2. 自定义Task开发 - Task依赖控制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Gradle是如何实现增量构建以提升效率的？请根据文档中的 `generateReports` 任务示例说明。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Gradle通过追踪任务的输入（inputs）和输出（outputs）状态来实现增量构建。在 `generateReports` 示例中，通过声明 `inputs.dir` 和 `outputs.dir`，Gradle能够检测输入文件是否发生变化。只有当输入文件发生变化时，任务才会再次执行，否则会跳过执行，从而节省时间。</div>
          </div>
          <div class="card-source">来源: 2. 自定义Task开发 - 增量构建示例</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">在多模块项目中，如何高效地为所有子模块提取并应用公共配置（如插件、仓库和依赖）？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">可以在根项目的 `build.gradle` 文件中使用 `subprojects` 配置块。在该块中定义的配置，例如应用 `java` 插件、设置 `repositories` 和添加通用 `dependencies`，会自动应用到所有子模块中。</div>
          </div>
          <div class="card-source">来源: 3. 多模块项目管理 - 公共配置提取</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在多模块项目中，`settings.gradle` 文件的核心作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`settings.gradle` 文件的核心作用是定义项目的结构，通过 `include` 指令声明哪些子模块是当前构建的一部分。它还用于设置根项目的名称。</div>
          </div>
          <div class="card-source">来源: 3. 多模块项目管理 - settings.gradle配置</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">如何应用一个本地的自定义脚本插件（例如 `gradle/quality.gradle`）到项目中？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过在主 `build.gradle` 文件中使用 `apply from: 'gradle/quality.gradle'` 语法，可以将指定路径下的脚本插件应用到构建中。</div>
          </div>
          <div class="card-source">来源: 4. 插件系统 - 自定义脚本插件</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">请列出 `gradle.properties` 文件中用于优化构建性能的四个关键配置项及其作用。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. `org.gradle.parallel=true`：启用并行构建，同时执行不相关的任务。<br>2. `org.gradle.caching=true`：启用构建缓存，重用之前任务的输出。<br>3. `org.gradle.daemon=true`：启用守护进程，避免每次构建都重新启动JVM。<br>4. `org.gradle.jvmargs`：为Gradle守护进程分配更多内存，例如 `-Xmx4g`。</div>
          </div>
          <div class="card-source">来源: 5. 构建性能优化 - 关键配置项</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">当需要分析和诊断构建性能问题时，应该使用什么命令来生成构建扫描报告？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">应该使用 `./gradlew build --scan` 命令。执行后会生成一个在线的、可交互的构建报告，用于深入分析构建过程的各个环节和性能瓶颈。</div>
          </div>
          <div class="card-source">来源: 5. 构建性能优化 - 构建扫描分析</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
